using System;
using dnAnalytics.Nli;

/// <summary>
/// Matrix vector multiplication where the matrix is a packed, symmetric matrix.
/// y = alpha*a*x + beta * y, where a is a matrix, and x and y are vectors.
/// </summary>
internal class Program {
	[STAThread]
	private static void Main() {
		//use the MKL BLAS provider
		IBlas blas = Blas.Provider(BlasProvider.Mkl);

		/* 
		 Let work this symmetric matrix:
		 1 2 3
		 2 4 5
		 3 5 6
		 
		 storing the data in the upper triangle -  
		 a packed, row major array would be:
		 {1, 2, 3, 4, 5, 6}

		 a packed, column major array would be:
		 {1, 2, 4, 3, 5, 6}


		 storing the data in the lower triangle -  
		 a packed, row major array would be:
		 {1, 2, 4, 3, 5, 6}

		 a packed, column major array would be:
		 {1, 2, 3, 4, 5, 6}

		*/		
		
		double[] ap = new double[] {1, 2, 3, 4, 5, 6};
		double[] x = new double[] {1, 1, 1};
		double[] y = new double[] {0, 0, 0};
		double alpha = 1;
		double beta = 0;

		blas.Dspmv(BlasOrderType.Row, BlasUpLoType.Upper, 3, alpha, ap, x, 1, beta, y, 1);
		foreach(double value in y) {
			Console.WriteLine(value);
		}
		Console.WriteLine();
		

		//which is the same as
		ap = new double[] {1, 2, 4, 3, 5, 6};
		blas.Dspmv(BlasOrderType.Column, BlasUpLoType.Upper, 3, alpha, ap, x, 1, beta, y, 1);
		foreach(double value in y) {
			Console.WriteLine(value);
		}
		Console.WriteLine();

		//which is the same as
		ap = new double[] {1, 2, 4, 3, 5, 6};
		blas.Dspmv(BlasOrderType.Row, BlasUpLoType.Lower, 3, alpha, ap, x, 1, beta, y, 1);
		foreach(double value in y) {
			Console.WriteLine(value);
		}
		Console.WriteLine();
		

		//which is the same as
		ap = new double[] {1, 2, 3, 4, 5, 6};
		blas.Dspmv(BlasOrderType.Column, BlasUpLoType.Lower, 3, alpha, ap, x, 1, beta, y, 1);
		foreach(double value in y) {
			Console.WriteLine(value);
		}
		Console.WriteLine();
		/* 
		Output:
		6
		11
		14

		6
		11
		14

		6
		11
		14

		6
		11
		14
		*/
	}
}